/***************************************************
**
**	CharenderView.m
**
**	By Brian Hobbs (brian@ny.shl.com)
**
**	This is the main class of the bundle, sets
**	up the defaults, environment, text string, and
**	stuff.  Everything but the code in the initFrame:
**	method should be quite unsurprising.
**
**	This code is public domain.  Feel free to use
**	it in any way you wish.  I'd like to see any 
**	changes you make, tho.
**
**	Kudos to Sam Streeper for the Teapot code, from
**	which most of the BackSpace 3-D setup was "acquired".
**
****************************************************/

#import "CharenderView.h"

#define CHARENDERTEXTDEFAULT	"CharenderText"
#define CHARENDERFONTDEFAULT	"CharenderFont"
#define CHARENDERCOLORDEFAULT	"CharenderColor"
#define CHARENDERSURFDEFAULT	"CharenderSurf"
#define CHARENDERRESDEFAULT		"CharenderRes"

@implementation CharenderView

+ initialize
{
  static NXDefaultsVector CharenderDefaults={
    {CHARENDERTEXTDEFAULT,"Darkninja"},
    {CHARENDERFONTDEFAULT,"Helvetica"},
    {CHARENDERCOLORDEFAULT,"1.0 1.0 1.0"},
    {CHARENDERSURFDEFAULT,"2"},
    {CHARENDERRESDEFAULT,"30"},
    {NULL}};
  NXRegisterDefaults([NXApp appName], CharenderDefaults);
  return [super initialize];
}

- initFrame:(const NXRect *) theRect
{	
	// camera position points
	RtPoint fromP = {0,0,-5.0}, toP = {0,0,0};

	// light position points
	RtPoint lFromP = {30,20,-20};
	RtPoint lFromP2 = {-10,10,-10};
	RtPoint lFromP3 = {0,-10,-10};

	// the various 3Dkit object id''s that we will initialize here
	id ambientLight;
	id aLight;

	[super initFrame:theRect];

	// retrieve defaults
	[self getDefaults];

	[self inspector:(BSThinker())];
	
	[self setEyeAt:fromP toward:toP roll:0.0];
		
	theShader=[[N3DShader alloc] init];
	[theShader setUseColor:YES];
	[theShader setColor:colorDefault];
	[(N3DShader *)theShader setShader:"plastic"];

	textShape= (DN3DString *)[[DN3DString alloc] init];
	[textShape setTextFont:fontDefault];
	[textShape setTextString:textDefault];
	textBox = [[N3DShape alloc] init];
	  
	[textShape setShader:theShader];
//	[[self setWorldShape:textShape] free];

	[[self worldShape] linkDescendant:textBox];
	[textBox linkDescendant:textShape];

	ambientLight=[[N3DLight alloc] init];
	[ambientLight makeAmbientWithIntensity:0.1];
	[self addLight:ambientLight];
	
	aLight=[[N3DLight alloc] init];
	[aLight makeDistantFrom:lFromP to:toP intensity:0.2];
	[self addLight:aLight];

	aLight=[[N3DLight alloc] init];
	[aLight makeDistantFrom:lFromP2 to:toP intensity:0.9];
	[self addLight:aLight];

	aLight=[[N3DLight alloc] init];
	[aLight makeDistantFrom:lFromP3 to:toP intensity:0.3];
	[self addLight:aLight];

	[self setSurfaceTypeForAll:surfaceTypeDefault chooseHider:YES];

	dx = randBetween(.05, .2);
	dy = randBetween(.05, .2);
	dz = randBetween(.05, .2);
	rotationAxis[0] = 0;
	theta = 0;

	return self;
}
	
#define PI 3.14159

- oneStep
{
	RtMatrix m;

	rotationAxis[1] = sin(theta);
	rotationAxis[2] = cos(theta);
	theta += (2.0 * PI / 180.0);

	[textShape rotateAngle:5 axis:rotationAxis];
	[textBox translate:dx :dy :dz];

	[textBox getTransformMatrix:m];

// I can use these values directly only because string's box isn't rotated
	if (m[3][0] < -1.5) dx = randBetween(.02, .1);
	else if (m[3][0] > 1.5) dx = randBetween(-.02, -.1);
	if (m[3][1] < -1.0) dy = randBetween(.02, .1);
	else if (m[3][1] > 1.5) dy = randBetween(-.02, -.1);
	if (m[3][2] < -2.25) dz = randBetween(.02, .1);
	else if (m[3][2] > 4) dz = randBetween(-.02, -.1);

	[self display];

	return self;
}

- (BOOL) useBufferedWindow
{
	return YES;
}

- (const char *)windowTitle
{	return "Charender";
}

- inspector:sender
{
    char buf[MAXPATHLEN];
	
    if (!inspectorPanel)
	{
		sprintf(buf,"%s/Charender.nib",[sender  moduleDirectory:"Charender"]);
		[NXApp loadNibFile:buf owner:self withNames:NO];

		[stringField setStringValue:textDefault];
		[stringField setFont:[Font newFont:fontDefault size:12.0]];
		[colorWell setColor:colorDefault];
		[surfaceMatrix selectCellAt:surfaceTypeDefault :0];
		[resolutionTextField setIntValue:resolutionDefault];
		[resolutionSlider setIntValue:resolutionDefault];
		
		[inspectorPanel display];
		NXPing();
    }
    return inspectorPanel;
}

- setStringAndFontFrom:sender
{
	strcpy(textDefault, [sender stringValue]);
	strcpy(fontDefault, [[sender font] name]);
	
	[textShape setTextString:textDefault andFont:fontDefault];
	
	NXWriteDefault([NXApp appName], CHARENDERTEXTDEFAULT, textDefault);
	NXWriteDefault([NXApp appName], CHARENDERFONTDEFAULT, fontDefault);

	[self display];
	
	return self;
}
		
- setColorFrom:sender
{
    float r,g,b;
    char str[100];

	colorDefault = [sender color];
	
	[theShader setColor:colorDefault];

    NXConvertColorToRGB(colorDefault, &r, &g, &b);
    sprintf(str, "%5.3f %5.3f %5.3f", r, g, b );
	NXWriteDefault([NXApp appName], CHARENDERCOLORDEFAULT, str);

	[self display];

	return self;
}

- setSurfaceTypeFrom:sender
{
	char str[100];

	surfaceTypeDefault = [sender selectedRow];
	
	sprintf(str,"%d", surfaceTypeDefault);
	NXWriteDefault([NXApp appName], CHARENDERSURFDEFAULT, str);

	[self setSurfaceTypeForAll:surfaceTypeDefault chooseHider:YES];

	[self display];

	return self;
}

- setResolutionFrom:sender
{
	char str[100];

	resolutionDefault = [sender intValue];

	sprintf(str,"%d", resolutionDefault);
	NXWriteDefault([NXApp appName], CHARENDERRESDEFAULT, str);
	
	[textShape setResolution:(float)resolutionDefault];
	[resolutionTextField setIntValue:resolutionDefault];
	
	[self display];
	
	return self;
}

- getDefaults
{
	const char *ptr;
	float r, g, b;
	
	textDefault = (char *)NXZoneMalloc([self zone], sizeof(char) * 80);
	fontDefault = (char *)NXZoneMalloc([self zone], sizeof(char) * 80);

	ptr = NXGetDefaultValue([NXApp appName], CHARENDERTEXTDEFAULT);
		strcpy(textDefault, (char *)ptr);

	ptr = NXGetDefaultValue([NXApp appName], CHARENDERFONTDEFAULT);
		strcpy(fontDefault, (char *)ptr);

	ptr = NXGetDefaultValue([NXApp appName], CHARENDERCOLORDEFAULT);
    	sscanf (ptr, "%f %f %f", &r, &g, &b );
		colorDefault = NXConvertRGBToColor(r,g,b);

	surfaceTypeDefault = atoi(NXGetDefaultValue([NXApp appName], CHARENDERSURFDEFAULT));
	
	resolutionDefault = atoi(NXGetDefaultValue([NXApp appName], CHARENDERRESDEFAULT));
	
	return self;
}

@end
